﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.Security;
using System.Security.Permissions;

namespace SPAzureBlobField.Classes
{
    public class SPAzureBlobField : SPFieldText
    {
        // Dictionary to store values to creation time bug.
        private static Dictionary<string, string> updatedCustomProperties = new Dictionary<string, string>();

        // Private variables holding custom property values.
        private string azureAccountName;
        private string azureAccountKey;
        private string azureAccountBlobContainer;

        private string ContextId
        {
            get
            {
                return SPContext.Current.GetHashCode().ToString();
            }
        }

        public SPAzureBlobField(SPFieldCollection fields, string fieldName)
            : base(fields, fieldName)
        {
            this.Init();
        }

        public SPAzureBlobField(SPFieldCollection fields, string typeName, string displayName)
            : base(fields, typeName, displayName)
        {
            this.Init();
        }

        private void Init()
        {
            // Setting Field properties from custom properties.
            this.AzureAccountName = this.GetCustomProperty("AzureAccountName") + "";
            this.AzureAccountKey = this.GetCustomProperty("AzureAccountKey") + "";
            this.AzureAccountBlobContainer = this.GetCustomProperty("AzureAccountBlobContainer") + "";
        }

        private void RemoveValuesFromDictionary()
        {
            if (updatedCustomProperties.ContainsKey(ContextId + "AzureAccountName"))
                updatedCustomProperties.Remove(ContextId + "AzureAccountName");
            if (updatedCustomProperties.ContainsKey(ContextId + "AzureAccountKey"))
                updatedCustomProperties.Remove(ContextId + "AzureAccountKey");
            if (updatedCustomProperties.ContainsKey(ContextId + " AzureAccountBlobContainer"))
                updatedCustomProperties.Remove(ContextId + "AzureAccountBlobContainer");
        }

        public override BaseFieldControl FieldRenderingControl
        {
            [SharePointPermission(SecurityAction.LinkDemand, ObjectModel = true)]
            get
            {
                BaseFieldControl fieldControl = new SPAzureBlobControl();
                fieldControl.FieldName = this.InternalName;
                return fieldControl;
            }
        }

        public override void OnAddingToContentType(SPContentType contentType)
        {
            // TODO check for container existence.
            base.OnAddingToContentType(contentType);
        }

        public override void Update()
        {
            // Trick to save values in custom properties, looks like SP is overwriting entries with previous values if done before...
            this.SetCustomProperty("AzureAccountName", this.AzureAccountName);
            this.SetCustomProperty("AzureAccountKey", this.AzureAccountKey);
            this.SetCustomProperty("AzureAccountBlobContainer", this.AzureAccountBlobContainer);
            base.Update();

            // Inserting the ClientAccessPolicy.xml in the Azure Storage account to allow SL client to access it.
            AzureStorageManager.CreateSilverlightPolicy(this.AzureAccountName, this.AzureAccountKey);

            // Trick to remove saved values from dictionary once saved.
            this.RemoveValuesFromDictionary();
        }

        public override void OnAdded(SPAddFieldOptions op)
        {
            base.OnAdded(op);
            // Update based on values saved on the static dictionary.
            Update();
        }

        public override string GetValidatedString(object value)
        {
            return base.GetValidatedString(value);
        }

        public void UpdateCustomProperty(string customFieldName, string value)
        {
            updatedCustomProperties[ContextId + customFieldName] = value;
        }

        public string AzureAccountName
        {
            get
            {
                return updatedCustomProperties.ContainsKey(ContextId + "AzureAccountName") ?
                    updatedCustomProperties[ContextId + "AzureAccountName"] : azureAccountName;
            }

            set
            {
                this.azureAccountName = value;

            }
        }

        public string AzureAccountKey
        {
            get
            {
                return updatedCustomProperties.ContainsKey(ContextId + "AzureAccountKey") ?
                updatedCustomProperties[ContextId + "AzureAccountKey"] : azureAccountKey;
            }

            set
            {
                this.azureAccountKey = value;
            }
        }

        public string AzureAccountBlobContainer
        {
            get
            {
                return updatedCustomProperties.ContainsKey(ContextId + "AzureAccountBlobContainer") ?
                    updatedCustomProperties[ContextId + "AzureAccountBlobContainer"] : azureAccountBlobContainer;
            }

            set
            {
                this.azureAccountBlobContainer = value;
            }
        }

        public override string GetFieldValueForEdit(object value)
        {
            return base.GetFieldValueForEdit(value);
        }

        public override object GetFieldValue(string value)
        {
            return base.GetFieldValue(value);
        }

        public override string GetFieldValueAsHtml(object value)
        {
            return base.GetFieldValueAsHtml(value);
        }
    }
}
